﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

namespace Utility.FSM
{
	public interface IStateScript
	{
		void OnInit (State state);

		void OnEnterState (State state, Agent agent, object context);
		void OnExitState (State state, Agent agent, object context);
		void OnArriveState (State state, Agent agent, object context);

		void OnUpdateState (State state, Agent agent, object context);
		void OnCaptureUpdateState (State state, Agent agent, object context);

		bool OnSignal (string signal, State state, Agent agent, object context);
		bool OnCaptureSignal (string signal, State state, Agent agent, object context);
	}

	public class BaseStateScript : IStateScript
	{
		public State FSMState { get; protected set; }

		public virtual void OnInit (State state)
		{
			FSMState = state;
		}

		public virtual void OnEnterState (State state, Agent agent, object context) { }
		public virtual void OnExitState (State state, Agent agent, object context) { }
		public virtual void OnArriveState (State state, Agent agent, object context) { }

		public virtual void OnUpdateState (State state, Agent agent, object context) { }
		public virtual void OnCaptureUpdateState (State state, Agent agent, object context) { }

		public virtual bool OnSignal (string signal, State state, Agent agent, object context)
		{
			return false;
		}
		public virtual bool OnCaptureSignal (string signal, State state, Agent agent, object context)
		{
			return false;
		}

	}

	public class BaseStateScript<TAgentScript> : IStateScript
		where TAgentScript : IAgentScript
	{
		public State FSMState { get; protected set; }

		public virtual void OnInit (State state)
		{
			FSMState = state;
		}

		public virtual void OnEnterState (State state, TAgentScript agent, object context) { }
		public virtual void OnExitState (State state, TAgentScript agent, object context) { }
		public virtual void OnArriveState (State state, TAgentScript agent, object context) { }

		public virtual void OnUpdateState (State state, TAgentScript agent, object context) { }
		public virtual void OnCaptureUpdateState (State state, TAgentScript agent, object context) { }

		public virtual bool OnSignal (string signal, State state, TAgentScript agent, object context)
		{
			return false;
		}
		public virtual bool OnCaptureSignal (string signal, State state, TAgentScript agent, object context)
		{
			return false;
		}


		void IStateScript.OnInit (State state)
		{
			OnInit (state);
		}
		void IStateScript.OnArriveState (State state, Agent agent, object context)
		{
			OnArriveState (state, agent.GetScript<TAgentScript> (), context);
		}
		void IStateScript.OnEnterState (State state, Agent agent, object context)
		{
			OnEnterState (state, agent.GetScript<TAgentScript> (), context);
		}
		void IStateScript.OnExitState (State state, Agent agent, object context)
		{
			OnExitState (state, agent.GetScript<TAgentScript> (), context);
		}

		void IStateScript.OnUpdateState (State state, Agent agent, object context)
		{
			OnUpdateState (state, agent.GetScript<TAgentScript> (), context);
		}
		void IStateScript.OnCaptureUpdateState (State state, Agent agent, object context)
		{
			OnCaptureUpdateState (state, agent.GetScript<TAgentScript> (), context);
		}

		bool IStateScript.OnSignal (string signal, State state, Agent agent, object context)
		{
			return OnSignal (signal, state, agent.GetScript<TAgentScript> (), context);
		}
		bool IStateScript.OnCaptureSignal (string signal, State state, Agent agent, object context)
		{
			return OnCaptureSignal (signal, state, agent.GetScript<TAgentScript> (), context);
		}
	}
}
